"""
为其它对象提供一种代理以控制对这个对象的访问。角色有抽象实体、实体和代理。应用场景有；；下面是不使用虚代理的例子：

角色：
    抽象实体（Subject）
    实体（RealSubject）
    代理（Proxy）
"""

from abc import ABCMeta, abstractmethod


# 抽象实体（Subject）
class Subject(metaclass=ABCMeta):
    """读取文件写入文件"""

    @abstractmethod
    def get_content(self):
        pass

    @abstractmethod
    def set_content(self, content):
        pass


# 实体（RealSubject）
class RealSubject(Subject):

    def __init__(self, filename):
        self.filename = filename
        print("读取文件内容！")
        with open(self.filename, "r", encoding="UTF-8") as f:
            self.centent = f.read()
            print(self.centent)

    def get_content(self):
        return self.centent

    def set_content(self, content):
        print("写入文件内容！")
        with open(self.filename, "w", encoding="UTF-8") as f:
            f.write(content)


# 代理（Proxy）
class VirtualProxy(Subject):
    def __init__(self, filename):
        self.filename = filename
        self.sub = None

    def get_content(self):
        if not self.sub:
            self.sub = RealSubject(self.filename)
        return self.sub.get_content()

    def set_content(self, content):
        if not self.sub:
            self.sub = RealSubject(self.filename)
        return self.sub.set_content(content)


class ProtectedSubject(Subject):
    """保护模式"""

    def __init__(self, sub):
        self.sub = sub

    def get_content(self):
        return self.sub.get_content()

    def set_content(self, content):
        raise Exception("没有写入权限")


# 不使用虚代理
# rs = RealSubject("test.txt")
# rs.set_content("1111")
# rs.get_content()

# 使用虚代理，使用一个代理去操作我们的实体
# vp = VirtualProxy("test.txt")  # 使用一个代理去操作我们的实体
# vp.get_content()
# vp.set_content("2222")

# 保护模式
ps = ProtectedSubject(RealSubject("test.txt"))
ps.get_content()
ps.set_content("44444")